package sketch.generator;

import randoop.StatementKind;
import sketch.ExecutableSequenceContent;
import sketch.MethodExecOutcome;
import sketch.SMethod;
import sketch.SketchSequence;
import sketch.util.Checker;
import sketch.util.SketchUtil;

public class RepeatSequenceGenerator<T extends SketchSequence> extends SingleSequenceGenerator<T> {

	private int repeated = 1;
	
	public RepeatSequenceGenerator(Object receiver, SMethod smethod, ValueGenerator<? extends Object> generator) {
		super(receiver, smethod, generator);
	}
	
	public RepeatSequenceGenerator(Object receiver, SMethod smethod, ValueGenerator<? extends Object> generator, int repeated) {
		this(receiver, smethod, generator);
		if(repeated < 1) {
			throw new RuntimeException("Can not repeat less than 1 time!");
		}
		this.repeated = repeated;
	}
	
	@Override
	public ExecutableSequenceContent[] executables() {
		throw new UnsupportedOperationException("executables() is not supported in RepeatSequenceGenerator!");
	}
//	
//	@Override
//	public Object[] evaluate() {
//		throw new UnsupportedOperationException("evaluate() is not supported in RepeatSequenceGenerator.");
//	}
	
	@Override
	public SketchSequence composeSequence() {
		if(!super.valueGenerator.hasNext()) {
			throw new IterationException("There is no more value for ValueGenerator.");
		}
		
		String lookupMethodName = super.smethod.getMethodNames()[0];
		StatementKind s = GenTests.lookupForStatement(this.smethod.sclazz.clazz, lookupMethodName);
		Checker.checkNull(s, "StatementKind for method: " +lookupMethodName + " is null!");
		
		SketchSequence sequence = new SketchSequence();
		while(super.valueGenerator.hasNext()) {
			Object arg = super.valueGenerator.next();
			//System.out.println("arg: " + arg + ", in " + super.valueGenerator.getClass());
//			sequence.add("calling: " + super.reciever.getClass() + ": " + super.smethod.getMethodNames()[0]
//			    + " with value: " + arg);    
			sequence.addText(SketchSequence.RECEIVER//SketchUtil.createVarName(super.getReceiver().getClass())
					+ "." + super.smethod.getMethodNames()[0] + "(" +  arg + ");");
			
//			ReflectionExecutionOutcome execResult = ReflectiveExecutions.reflectiveExecute(super.getReceiver(), s, arg);
//			System.out.println("repeatedly execution generation, " + execResult + ", the object id of receiver: " + super.getReceiverId());
//			ExecutableSequenceContent content = new ExecutableSequenceContent(super.getReceiver(), s, arg);
//			sequence.addExecutableContent(content);
		}
		
		sequence = sequence.repeatAll(repeated);
		
		return sequence;
	}
	
//	@Override
//	protected MethodExecOutcome[] executionResult() {
//		MethodExecOutcome[] outcomes = super.executionResult();
//		if(outcomes == null) {
//			return null;
//		}
//		
//		int repeatedSize = this.repeated + 1;
//		MethodExecOutcome[] repeatedOutcomes = new MethodExecOutcome[repeatedSize];
//		for(int i = 0; i < repeatedSize; i++) {
//			repeatedOutcomes[i] = new MethodExecOutcome();
//		}
//		return repeatedOutcomes;
//	}
	
}
